﻿using System;
using nRoute.Internal;

namespace nRoute.Components
{
    public sealed class DisposableToken
        : IDisposableToken
    {
        private readonly Object _lock = new Object();
        private Action _disposableCallback;
        private volatile bool _isDisposed;

        public DisposableToken() { }

        public DisposableToken(Action disposableCallback)
        {
            _disposableCallback = disposableCallback;
        }

#region IDisposableToken Members

        public bool IsDisposed
        {
            get { return _isDisposed; }
        }

#endregion

#region IDisposable Members

        public void Dispose()
        {
            Dispose(true);
            GC.SuppressFinalize(this);
        }

        public void Dispose(bool withCallback)
        {
            if (!_isDisposed)
            {
                lock (_lock)
                {
                    if (!_isDisposed)
                    {
                        if (withCallback && _disposableCallback != null) _disposableCallback();
                        _disposableCallback = null;
                        _isDisposed = true;
                    }
                }
            }
        }

#endregion

    }
}

//public sealed class CancellationToken
//    : ICancellable, IDisposable
//{
//    public readonly static CancellationToken Empty = new CancellationToken();

//    private Action _cancellationCallback = null;
//    private volatile bool? _isCancelled;
//    private readonly Object _lock = new object();

//    private CancellationToken() { }

//    public CancellationToken(Action cancellationCallback)
//    {
//        Guard.ArgumentNotNull(cancellationCallback, "cancellationCallback");
//        _cancellationCallback = cancellationCallback;
//        _isCancelled = false;
//    }

//    #region Properties

//    public bool IsCancellable
//    {
//        get { return !_isCancelled.GetValueOrDefault(true); }
//    }

//    #endregion

//    #region ICancellable Members

//    public void Cancel()
//    {
//        if (!IsCancelled)
//        {
//            lock (_lock)
//            {
//                if (_cancellationCallback != null)
//                {
//                    _cancellationCallback.Invoke();
//                    _cancellationCallback = null;
//                    _isCancelled = true;
//                }
//            }
//        }
//    }

//    public bool IsCancelled
//    {
//        get { return _isCancelled.GetValueOrDefault(false); }
//    }

//    #endregion

//    #region IDisposable Members

//    public void Dispose()
//    {
//        Dispose(true);
//        GC.SuppressFinalize(this);
//    }

//    private void Dispose(bool disposing)
//    {
//        if (disposing)
//        {
//            lock (_lock)
//            {
//                _cancellationCallback = null;
//            }
//        }
//    }

//    #endregion

//}
